Skip to content

fix(proxy): honor an explicit max_tokens instead of overwriting it#115

Merged
VickyXAI merged 1 commit into
mainfrom
fix/proxy-honor-explicit-max-tokens
Jul 21, 2026
Merged

fix(proxy): honor an explicit max_tokens instead of overwriting it#115
VickyXAI merged 1 commit into
mainfrom
fix/proxy-honor-explicit-max-tokens

Conversation

@VickyXAI

Copy link
Copy Markdown
Contributor

Found while reviewing #113. Flagged there, fixed here.

The bug

The proxy replaced whatever the caller sent with min(adaptive, modelCap), where adaptive is twice the previous reply on that model. A client asking for 500 tokens right after a long turn was forwarded several thousand instead.

That is not just a bigger number. The gateway derives its price quote from the ceiling a request asks for — quotedOutputTokens = maxOutputTokens * OUTPUT_QUOTE_FACTOR — so the overwrite inflated the upfront hold on a request the caller had deliberately kept small. Settlement is on actual usage, so nobody was overcharged; the amount held just wasn't the amount asked for.

Old mechanism, new blast radius

The overwrite predates this session. What changed is reach: raising MODEL_MAX_OUTPUT in 3.35.2 / 3.35.4 / 3.35.5 lifted modelCap for several models from 16,384–32,768 to 128,000, so the overwrite could push roughly 4× further than before.

Same shape as the gateway ceiling raise in BlockRunAI/blockrun#266, which needed a context-headroom guard (#268) added after the fact: raising a ceiling disturbs code that quietly relied on it being low.

The fix

caller sent before after
500 (after a 20k reply) 40,000 500
omitted (after a 10k reply) 20,000 20,000 — unchanged
omitted (no history) 4,096 4,096 — unchanged
999999 128,000 128,000 — still clamped

An explicit, positive, finite ask is honored; only a missing or unusable one gets the adaptive default. Clamping to modelCap stays on both paths — asking past a model's own ceiling is a request the provider rejects outright, and failing it here is worse than quietly making it legal.

Why it went unnoticed

The decision was buried inline in the request handler with no way to test it. Extracted to resolveProxyMaxTokens() and exported.

Four tests: the explicit path, the adaptive path, clamping on both, and junk input (0, -1, NaN, Infinity, '4096', {}, true) falling back rather than propagating into a payment quote.

Local suite 640 pass, 0 fail.

The proxy replaced whatever the caller sent with min(adaptive, modelCap),
where adaptive is twice the previous reply on that model. A client asking for
500 tokens right after a long turn was forwarded several thousand instead.

That is not just a bigger number. The gateway derives its price quote from the
ceiling a request asks for (quotedOutputTokens = maxOutputTokens *
OUTPUT_QUOTE_FACTOR), so the overwrite inflated the upfront hold on a request
the caller had deliberately kept small. Settlement is on actual usage, so
nobody was overcharged — but the amount held was not the amount asked for.

The mechanism predates this session. What changed is reach: raising
MODEL_MAX_OUTPUT in 3.35.2, 3.35.4 and 3.35.5 lifted modelCap for several
models from 16384/32768 to 128000, so the overwrite could push roughly 4x
further than before. Old mechanism, new blast radius — the same shape as the
gateway ceiling raise that needed a headroom guard added after the fact.

Now: an explicit, positive, finite ask is honored; only a missing or unusable
one gets the adaptive default. Clamping to modelCap stays on both paths, since
asking past a model's own ceiling is a request the provider rejects outright
and failing it here is worse than quietly making it legal.

Extracted the decision into resolveProxyMaxTokens() and exported it. It was
buried in the request handler with no way to test it, which is why the
overwrite went unnoticed. Four tests now cover the explicit path, the adaptive
path, clamping on both, and junk input (0, -1, NaN, Infinity, '4096', {},
true) falling back rather than propagating.

Local suite 640 pass.
@VickyXAI
VickyXAI merged commit 9f40912 into main Jul 21, 2026
2 checks passed
@VickyXAI
VickyXAI deleted the fix/proxy-honor-explicit-max-tokens branch July 21, 2026 16:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant